<?php
/**
 * @ClassName: Equipment
 * @Description: TODO
 * @author: gydtrade
 * @Date: 2025-11-13 15:07
 * @Version: V1.0.0
 */

namespace app\admin\controller;

use app\common\enum\RackEnum;
use app\common\logic\EquipmentLogic;
use app\common\model;
use PhpOffice\PhpSpreadsheet\Reader\Xls;
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xls as XlsWriter;
use think\Controller;
use think\Db;
use think\facade\Log;
use tpext\builder\traits\HasBuilder;

class Equipment extends Controller
{
    use HasBuilder;

    protected $dataModel;

    protected function initialize()
    {
        parent::initialize();

        $this->dataModel = new model\Equipment();
        $this->pageTitle = '设备管理';
        $this->pagesize = 10;

        $this->indexWith = [];
    }

    /**
     * 构建搜索
     *
     * @return void
     */
    protected function buildSearch()
    {
        $search = $this->search;

        $search->text('name', '设备名称');
        $search->select('device_type', '设备类型')->dataUrl(url("/admin/equipmenttype/selectPage"));
        $search->text('device_no', '设备编号');
        $search->text('device_sid', '设备号');
        $search->text('out_device_sid', '板子编号');
        $search->text('flow_card_no', '流量卡编号');

        $search->select('holder_type', '持有人')->options(model\Equipment::$holder_types)->when(model\Equipment::holder_type_center)->with(
            $search->select('h_related_id', '运营中心', 12)->dataUrl(url("/admin/agent.operation/selectPage"))
        )->when(model\Equipment::holder_type_agent)->with(
            $search->select('h_related_id', '代理', 12)->dataUrl(url("/admin/agent.agent/selectPage"))
        )->when(model\Equipment::holder_type_store)->with(
            $search->select('h_related_id', '门店', 12)->dataUrl(url("/admin/store.store/selectPage"))
        );

        $search->select('use_type', '使用人')->options(model\Equipment::$use_types)->when(model\Equipment::use_type_center)->with(
            $search->select('u_related_id', '运营中心', 12)->dataUrl(url("/admin/agent.operation/selectPage"))
        )->when(model\Equipment::use_type_agent)->with(
            $search->select('u_related_id', '代理', 12)->dataUrl(url("/admin/agent.agent/selectPage"))
        )->when(model\Equipment::use_type_store)->with(
            $search->select('u_related_id', '门店', 12)->dataUrl(url("/admin/store.store/selectPage"))
        )->when(model\Equipment::use_type_customer)->with(
            $search->select('u_related_id', '客户', 12)->dataUrl(url("/admin/customer.customer/selectPage"))
        )->when(model\Equipment::use_type_user)->with(
            $search->select('u_related_id', '会员', 12)->dataUrl(url("/admin/member/selectPage"))
        );
        $search->select('status', '设备状态')->options(RackEnum::statusText(true));
        $search->select('sales_method', '销售方式')->options(model\Equipment::$sales_methods);

        $search->datetime('allocate_start', '划拨时间')->placeholder('起始');
        $search->datetime('allocate_end', '~')->placeholder('截止');

        $search->datetime('renew_start', '续费时间')->placeholder('起始');
        $search->datetime('renew_end', '~')->placeholder('截止');
    }

    /**
     * 构建搜索条件
     * @return array
     */
    protected function filterWhere()
    {
        $searchData = request()->get();

        $where = [];
        if (isset($searchData['name']) && $searchData['name'] != '') {
            $where[] = ['name', 'like', '%' . trim($searchData['name']) . '%'];
        }
        if (isset($searchData['device_type']) && $searchData['device_type'] != '') {
            $where[] = ['device_type', '=', $searchData['device_type']];
        }
        if (isset($searchData['device_no']) && $searchData['device_no'] != '') {
            $where[] = ['device_no', 'like', '%' . trim($searchData['device_no']) . '%'];
        }
        if (isset($searchData['device_sid']) && $searchData['device_sid'] != '') {
            $where[] = ['device_sid', 'like', '%' . trim($searchData['device_sid']) . '%'];
        }
        if (isset($searchData['out_device_sid']) && $searchData['out_device_sid'] != '') {
            $where[] = ['out_device_sid', 'like', '%' . trim($searchData['out_device_sid']) . '%'];
        }
        if (isset($searchData['flow_card_no']) && $searchData['flow_card_no'] != '') {
            $where[] = ['flow_card_no', 'like', '%' . trim($searchData['flow_card_no']) . '%'];
        }
        if (isset($searchData['holder_type']) && $searchData['holder_type'] != '') {
            $where[] = ['holder_type', '=', $searchData['holder_type']];
        }
        if (isset($searchData['h_related_id']) && $searchData['h_related_id'] != '') {
            $where[] = ['h_related_id', '=', $searchData['h_related_id']];
        }
        if (isset($searchData['use_type']) && $searchData['use_type'] != '') {
            $where[] = ['use_type', '=', $searchData['use_type']];
        }
        if (isset($searchData['u_related_id']) && $searchData['u_related_id'] != '') {
            $where[] = ['u_related_id', '=', $searchData['u_related_id']];
        }
        if (isset($searchData['status']) && $searchData['status'] != '') {
            $where[] = ['status', '=', $searchData['status']];
        }
        if (isset($searchData['sales_method']) && $searchData['sales_method'] != '') {
            $where[] = ['sales_method', '=', $searchData['sales_method']];
        }
        if (!empty($searchData['allocate_start'])) {
            $where[] = ['allocate_time', 'egt', $searchData['allocate_start']];
        }
        if (!empty($searchData['allocate_end'])) {
            $where[] = ['allocate_time', 'elt', $searchData['allocate_end']];
        }
        if (!empty($searchData['renew_start'])) {
            $where[] = ['renew_time', 'egt', $searchData['renew_start']];
        }
        if (!empty($searchData['renew_end'])) {
            $where[] = ['renew_time', 'elt', $searchData['renew_end']];
        }

        return $where;
    }

    /**
     * 构建表格
     *
     * @return void
     */
    protected function buildTable(&$data = [])
    {
        $table = $this->table;

        $table->show('id', 'ID');
        $table->show('name', '设备名称');
        $table->show('device_type_str', '设备类型');
        $table->fields('device_info', '设备编号/设备号')->with(
            $table->show('device_no', '设备编号'),
            $table->show('device_sid', '设备号')
        );
        $table->show('out_device_sid', '板子编号');
        $table->show('flow_card_no', '流量卡编号');
        $table->fields('price', '年租金')->with(
            $table->show('rent', '基础金额'),
            $table->show('additional_amount', '加价金额'),
        );
        $table->show('holder_info', '设备持有人');
        $table->show('use_info', '设备使用人');
        $table->match('status', '设备状态')->options(RackEnum::statusText(true))->mapClassGroup([[-1, 'info'], [1, 'success'], [2, 'error']]);
        $table->match('sales_method', '销售方式')->options(model\Equipment::$sales_methods)->mapClassGroup([[1, 'info'], [2, 'success'], [3, 'error']]);
        $table->show('allocate_time', '最后划拨时间')->default('---');
        $table->fields('times_group', '添加/修改时间')->with(
            $table->show('create_time', '添加时间')->default('---'),
            $table->show('update_time', '修改时间')->default('---')
        )->getWrapper()->addStyle('width:160px');

        $table->sortable('id, create_time');

        $table->getToolbar()
            ->btnAdd()
            ->btnOpenChecked('allocate', '划拨', 'btn-info', 'mdi mdi-checkbox-marked-outline')
            ->btnImport(url('import'), 'xls,xlsx', ['800px', '550px'], 20, '设备批量导入')->html('<a href="/template/设备导入模板.xlsx">导入模板下载</a>')
            ->btnRefresh();

        $table->getActionbar()
            ->btnLink('allocate', url('allocate', ['ids' => '__data.id__']), '划拨', 'btn-info', 'mdi mdi-coin')
            ->btnEdit()
            ->btnView()
            ->br()
            ->btnLink('', url('/admin/equipmenttransferrecords/index', ['device_id' => '__data.id__']), '划拨记录', 'btn-info', 'mdi mdi-coin')
            ->btnLink('', url('/admin/equipmentcostrecords/index', ['device_id' => '__data.id__']), '费用记录', 'btn-info', 'mdi mdi-coin');
    }

    /**
     * 构建表单
     *
     * @param boolean $isEdit
     * @param array $data
     */
    protected function buildForm($isEdit, &$data = [])
    {
        $form = $this->form;

        $form->hidden('id');
        $device_config = web_config('device_config');

        $form->text('name', '设备名称')->required();
        $form->select('device_type', '设备类型')->dataUrl(url("/admin/equipmenttype/selectPage"))->required();
        $form->text('device_no', '设备编号')->required();
        $form->text('device_sid', '设备号')->required();
        $form->text('out_device_sid', '板子编号')->required();
        $form->text('flow_card_no', '流量卡编号')->required();
        $form->radio('sales_method', '销售方式')->options(model\Equipment::$sales_methods)->default(-1)->required();
        $form->text('rent', '年租金')->required()->default($device_config['basic_rental_fee']);
        $form->text('additional_amount', '加价金额')->default(0);
        $form->number('grids_num', '几格架子')->help('当类型为水架时，必填水架格数');

        if ($isEdit == 2) {
            $form->show('allocate_time', '最后划拨时间')->default('---');
            $form->show('activation_time', '激活时间')->default('---');
            $form->show('renew_time', '续费时间')->default('---');
        }

        if ($isEdit) {
            $form->show('create_time', '添加时间')->default('---');
            $form->show('update_time', '修改时间')->default('---');
        }
    }

    /**
     * 划拨
     * @return \think\response\Json|\tpext\builder\common\Builder|\tpext\think\View
     */
    public function allocate()
    {
        $builder = $this->builder('设备划拨');

        $ids = explode(',', input('ids', 0));
//        var_dump($ids);

        if (count($ids) == 0) {
            return $builder->layer()->closeRefresh(0, '请选择设备');
        }

        if (request()->isPost()) {
            $data = request()->post();
            $data['allocate_time'] = date_now();
//            var_dump('划拨提交', $data);

            unset($data['__token__']);

            if ($data['holder_type'] == model\Equipment::holder_type_center) {
                $data['center_id'] = $data['h_related_id'];
            }
            $device_config = web_config('device_config');
            $count = 0;
            foreach ($ids as $id) {
                $device = $this->dataModel->where('id', $id)->find();
                if ($device && !$device['activation_time']) {
                    $data['activation_time'] = date_now();//第一次划拨就算激活，开始一年倒计时
                    $data['expiration_time'] = date('Y-m-d H:i:s', strtotime('+' . $device_config['device_validity_period'] ?? '365' . ' days', time()));
                }
                $res = $this->dataModel->where('id', $id)->update($data);
                if ($res) {
                    //添加划拨记录
                    EquipmentLogic::addTransferRecords($id, 1, 0, $data['holder_type'], $data['h_related_id'], $data['remark']);
                    $count++;
                }
            }

            return $builder->layer()->closeRefresh(1, '划拨成功 ' . $count . ' 设备');
        }

        $form = $builder->form();

        $form->radio('holder_type', '划拨类型')->options(model\Equipment::$holder_types)->default(2)->required()
            ->when(model\Equipment::holder_type_center)->with(
                $form->select('h_related_id', '运营中心')->dataUrl(url("/admin/agent.operation/selectPage"))->required(),
            )->when(model\Equipment::holder_type_agent)->with(
                $form->select('h_related_id', '代理')->dataUrl(url('/admin/agent.agent/selectPage'))->required(),
            )->when(model\Equipment::holder_type_store)->with(
                $form->select('h_related_id', '门店')->dataUrl(url('/admin/store.store/selectPage'))->required(),
            );
        $form->radio('sales_method', '销售方式')->options(model\Equipment::$sales_methods)->default(1)->required();
        $form->text('rent', '年租金')->default(50)->required();
        $form->textarea('remark', '备注');

        $form->btnSubmit('划&nbsp;&nbsp;拨');
        return $builder;
    }

    /**
     * 导入
     * @return \think\response\Json|\tpext\think\View
     */
    public function import()
    {
        $fileurl = input('fileurl');

        $file = app()->getRootPath() . 'public' . $fileurl;
        if (!is_file($file)) {
            $builder = $this->builder('出错了');
            $builder->content()->display('<p>' . '未能读取文件:' . $fileurl . '</p>');
            return $builder->render();
        }
        $temp = explode(".", $fileurl);
        $ext = end($temp); // 获取文件后缀名

        if ($ext == 'xls') {
            $reader = new Xls();
        } else if ($ext == 'xlsx') {
            $reader = new Xlsx();
        } else {
            $reader = new Xls();
        }

        try {
            $PHPExcel = $reader->load($file);

            $sheet = $PHPExcel->getSheet(0); // 读取第一个工作表
            $highestRow = $sheet->getHighestRow(); // 取得总行数
        } catch (\Exception $ex) {
            Log::record($ex->__toString());
            $builder = $this->builder('出错了');

            $builder->content()->display('<p>' . '读取文件出错，可能是excel文件格式不规范，建议将文件【另存为】一个新文件，然后上传新文件' . '</p>');
            return $builder->render();
        }

        Db::startTrans();

        $error_row = [];
        $count = 0;
        $msg = [];
        $data = [];

        if ($sheet) {
            for ($rowIndex = 1; $rowIndex <= $highestRow; $rowIndex++) { //循环行数
                $device_type_name = trim($sheet->getCell("A" . $rowIndex)->getValue());

                $data['device_type'] = 0;
                $device_type = model\EquipmentType::where('name', $device_type_name)->find();
                if ($device_type) {
                    $data['device_type'] = $device_type['id'];
                }
                $data['name'] = trim($sheet->getCell("B" . $rowIndex)->getValue());
                $data['grids_num'] = trim($sheet->getCell("C" . $rowIndex)->getValue());
                $data['device_no'] = trim($sheet->getCell("D" . $rowIndex)->getValue());
                $data['device_sid'] = trim($sheet->getCell("E" . $rowIndex)->getValue());
                $data['flow_card_no'] = trim($sheet->getCell("F" . $rowIndex)->getValue());
                $data['out_device_sid'] = trim($sheet->getCell("G" . $rowIndex)->getValue());

                if (
                    strstr($data['name'], '设备名称') || $data['grids_num'] == '架子格数' || $data['device_no'] == '设备编号' ||
                    $data['device_sid'] == '设备号' || $data['flow_card_no'] == '流量卡编号' || $data['out_device_sid'] == '板子编号'
                ) { //判断表头
                    continue;
                }

                if (empty($data['device_type'])) {
                    $error_row[] = [$rowIndex, $data['device_type'], $data['name'], $data['grids_num'], $data['device_no'], $data['device_sid'], $data['flow_card_no'], $data['out_device_sid'], '[跳过]设备类型异常,A列'];
                    continue;
                }
                if (empty($data['name'])) {
                    $error_row[] = [$rowIndex, $data['device_type'], $data['name'], $data['grids_num'], $data['device_no'], $data['device_sid'], $data['flow_card_no'], $data['out_device_sid'], '[跳过]设备名称为空,B列'];
                    continue;
                }
                /*if (empty($data['grids_num'])) {
                    $error_row[] = [$rowIndex, $data['device_type'], $data['name'], $data['grids_num'], $data['device_no'], $data['device_sid'], $data['flow_card_no'], $data['out_device_sid'], '[跳过]架子格数为空,C列'];
                    continue;
                }*/
                if (empty($data['device_no'])) {
                    $error_row[] = [$rowIndex, $data['device_type'], $data['name'], $data['grids_num'], $data['device_no'], $data['device_sid'], $data['flow_card_no'], $data['out_device_sid'], '[跳过]设备编号为空,D列'];
                    continue;
                }
                if (empty($data['device_sid'])) {
                    $error_row[] = [$rowIndex, $data['device_type'], $data['name'], $data['grids_num'], $data['device_no'], $data['device_sid'], $data['flow_card_no'], $data['out_device_sid'], '[跳过]设备号为空,E列'];
                    continue;
                }
                /*if (empty($data['flow_card_no'])) {
                    $error_row[] = [$rowIndex, $data['device_type'], $data['name'], $data['grids_num'], $data['device_no'], $data['device_sid'], $data['flow_card_no'], $data['out_device_sid'], '[跳过]外部设备号为空,F列'];
                    continue;
                }*/
                /*if (empty($data['out_device_sid'])) {
                    $error_row[] = [$rowIndex, $data['device_type'], $data['name'], $data['grids_num'], $data['device_no'], $data['device_sid'], $data['flow_card_no'], $data['out_device_sid'], '[跳过]外部设备号为空,G列'];
                    continue;
                }*/

                try {
                    // 检查设备信息是否重复
                    $exist = $this->dataModel->where('device_no', $data['device_no'])
                        ->whereOr('device_sid', $data['device_sid'])
                        ->whereOr('flow_card_no', $data['flow_card_no'])
                        ->whereOr('out_device_sid', $data['out_device_sid'])
                        ->find();
                    if ($exist) {
                        $error_row[] = [$rowIndex, $data['device_type'], $data['name'], $data['grids_num'], $data['device_no'], $data['device_sid'], $data['flow_card_no'], $data['out_device_sid'], '[跳过]设备信息已存在'];
                        continue;
                    }

                    $res = $this->dataModel->create($data);

                    if (!$res) {
                        $error_row[] = [$rowIndex, $data['device_type'], $data['name'], $data['grids_num'], $data['device_no'], $data['device_sid'], $data['flow_card_no'], $data['out_device_sid'], '[跳过]设备信息导入失败'];
                    } else {
                        $count += 1;
                    }
                } catch (\Exception $e) {
                    $error_row[] = [$rowIndex, $data['device_type'], $data['name'], $data['grids_num'], $data['device_no'], $data['device_sid'], $data['flow_card_no'], $data['out_device_sid'], '[跳过]设备信息导入异常-' . $e->getMessage()];
                }
            }
        }

        Db::commit();

        if (!empty($error_row)) {
            $spreadsheet = new Spreadsheet();
            $sheet = $spreadsheet->getActiveSheet();
            $sheet->setCellValue('A1', '行号');
            $sheet->setCellValue('B1', '设备类型');
            $sheet->setCellValue('C1', '设备名称');
            $sheet->setCellValue('D1', '架子格数');
            $sheet->setCellValue('E1', '设备编号');
            $sheet->setCellValue('F1', '设备号');
            $sheet->setCellValue('G1', '流量卡编号');
            $sheet->setCellValue('H1', '板子编号');
            $sheet->setCellValue('I1', '状态');
            $i = 2;
            foreach ($error_row as $row) {
                $sheet->setCellValue('A' . $i, $row[0]);
                $sheet->setCellValue('B' . $i, $row[1]);
                $sheet->setCellValue('C' . $i, $row[2]);
                $sheet->setCellValue('D' . $i, $row[3]);
                $sheet->setCellValue('E' . $i, $row[4] . "\t");
                $sheet->setCellValue('F' . $i, $row[5] . "\t");
                $sheet->setCellValue('G' . $i, $row[6] . "\t");
                $sheet->setCellValue('H' . $i, $row[7] . "\t");
                $sheet->setCellValue('I' . $i, $row[8]);
                $i += 1;
            }

            $sheet->getColumnDimension('B')->setWidth(30);

            $writer = new XlsWriter($spreadsheet);
            $time = time();
            if (!is_dir('./uploads/download/')) {
                mkdir('./uploads/download/', 0755, true);
            }
            $writer->save('./uploads/download/equipment' . $time . '.xls');

            $msg[] = '本次导入出现错误：<a href="/uploads/download/equipment' . $time . '.xls">错误列表excel下载</a>';
        }

        @unlink($file);

        if ($count) {
            if (empty($msg)) {
                return $this->builder()->layer()->closeRefresh(1, '成功导入' . $count . '条数据。');
            }

            $builder = $this->builder('提示');
            $builder->content()->display('<p>成功导入' . $count . '条数据。</p><script>parent.$(".__page__").val(1);parent.$(".search-refresh").trigger("click");</script>' . implode('<br>', $msg));

            return $builder->render();
        } else {
            if (empty($msg)) {
                return $this->builder()->layer()->closeRefresh(0, '本次未导入任何数据');
            }
            $builder = $this->builder('提示');
            $builder->content()->display('<p>本次未导入任何数据。</p><script>parent.$(".search-refresh").trigger("click");</script>' . implode('<br>', $msg));
            return $builder->render();
        }
    }

    /**
     * 保存数据
     *
     * @param integer $id
     * @return void
     */
    private function save($id = 0)
    {
        $data = request()->post();

        $result = $this->validate($data, []);

        if (!$result) {
            $this->error($result);
        }

        if ($id) {
            // 编辑
            $data['update_time'] = date_now();
        } else {
            // 新增
            $data['status'] = -1; //设备入库，状态默认为待使用
            $data['create_time'] = date_now();
            $data['update_time'] = date_now();
        }

        return $this->doSave($data, $id);
    }
}